How to use vCurrent and “self” correctly in viewmodels

A simple mistake can mess up your ViewModel rendering, making it slow and unlike what you expected.

This is our example model, which lends itself to a simple master-detail view.

Simple Model vCurrent.png

The view we want is a list of Years - click a Year and that Year’s months will show. Then, click a Month, and that month’s Days will show.

Below are the different ViewModels which will show the same thing:

Different View Models.pngDifferent View Models 2.pngDifferent View Models 3.png

Both SendAndShowSelected and SendAllShowSelect are okay, but with different approaches to when data is sent to the client. SendWeirdAndShowSelected is not advisable but will show the same thing as the previous two.

So, what’s happening in these situations?

In a ViewModel, you have access to built-in variables called vCurrent_<name of viewmodelclass> and self. Self is what you would expect - the object rendered when the server iterates over the list for the ViewModel class you access self in. vCurrent_<name of viewmodelclass> are variables that are global to the entire ViewModel. Whenever you access vCurrent, you get the user-selected current object for the list of objects of the named class.

SendAndShowSelected

All Years, the current Month for the current Year, and all Days for the selected Months and Years will be fetched serverside and sent to the client. This is a minimum of fetched and sent data. This is probably the thing you want most of the time.

SendAllShowSelected

All Years, all Months for all Years, and all Days for all Months and all Years will be fetched serverside and ALL of them will be sent to the client. This is the maximum expanded tree that the ViewModel expresses. Why would you even want this? You want this if you have a custom component you want to process data client-side or it’s OK with a slight delay initially but with a swift experience thereafter.

SendWeirdAndShowSelected

Placing vCurrent* in the ViewModel as in the example above doesn't work out well. This is because the server, for example, with the Years, for every Year in the object list, vCurrent_AllYear evaluates to the same – what the user has clicked on.

Let’s say "Years" are a list of 2014, 2015, and 2016. If the user has clicked on 2015, the Months will be the months for 2015, even for 2014 and 2016. This means that the client is updated again and again with an incorrect list of months when the user clicks, but it still shows a correct view to the user - why? The user only sees the correct branch, but the client gets all these incorrect branch updates to their data without any good coming from it.

So, why is vCurrent* available in the blue ViewModel classes? It is usable, for example, in filtering a list on user selection in another list. If it’s not a master-detail relationship, it can be an easy way to add a sublist of objects to another ViewModel class.

Two Ways ViewModels Are Built

When the server renders/fills in a ViewModel, it does one of these:

  • Expands the whole “tree” with every object that the expressions specified in each branch, making a “full” tree.
  • Expands only the “”vCurrent” on each level, making a “sparse” tree.

Different Clients – Different Trees

For a WCF client with an ECO space in memory, sparse trees are built. This is because the client has access to the full object space anyway and can quickly rebuild the ViewModel tree upon user selection.

For Turnkey, i.e. streaming ViewModel clients, the server builds full trees and streams to the client. This is true for both Angular web UI and the WPF turnkey client.

Conclusion

In most cases, construct your ViewModels with master-detail relationships as shown in SendAndShowSelected.

If you want to increase performance by switching between different things in the view, consider using SendAllShowSelected. That means sending all data right away to the client and then only updating vCurrent-variables to switch between different data on the client.

The model used in this example: YearMonthDayExampleModel

You can also read about it here: https://blog.mdriven.net/cursored-or-full-tree/

This page was edited 107 days ago on 01/11/2024. What links here